
# 老师讲的双链表

class Node(object):
    def __init__(self, data=None):
        self.data = data
        self._next = None
        self._prev = None


class List(object):
    def __init__(self):
        self.head = Node()
        self.tail = Node()

        # intialize the head and tail vars.
        self.head.next = self.tail
        self.tail.prev = self.head

        self.length = 0 # 这个 length 还不能求吧

    def insert(self, pos, data):
        assert pos >= 0 and pos <= self.length

        # Find out the position to insert.
        tmpPtr = self.head #@1
        while pos > 0:
            tmpPtr = tmpPtr.next
            pos -= 1

        # Insert new node
        newNode = Node()
        newNode.data = data

        curNode = tmpPtr
        nextNode = tmpPtr.next

        curNode.next = newNode
        newNode.prev = curNode

        newNode.next = nextNode
        if nextNode:
            nextNode.prev = newNode

        self.length += 1



    def append(self, data):
        self.insert(self.length, data)

    def remove(self, pos):
        assert pos < self.length and pos >= 0

        tmpPtr = self.head.next #@2 和@1不一样 循环次数应该有问题吧
        while pos > 0:
            tmpPtr = tmpPtr.next
            pos -= 1

        prevNode = tmpPtr.prev
        nextNode = tmpPtr.next

        prevNode.next = nextNode
        if nextNode:
            nextNode.prev = prevNode

        self.length -= 1

    # def __len__(self): 注释掉:TypeError: object of type 'List' has no len()
    #     return self.length
    def __len__(self):
        return self.length

    def __iter__(self): # 迭代器
        tmpPtr = self.head.next
        while tmpPtr != self.tail:
            yield tmpPtr.data
            tmpPtr = tmpPtr.next

    def foreach(self, flag=True): #遍历
        if flag:
            tmpPtr = self.head.next
            while tmpPtr != self.tail:
                yield tmpPtr.data
                tmpPtr = tmpPtr.next
        else:
            tmpPtr = self.tail.prev
            while tmpPtr != self.head:
                yield tmpPtr.data
                tmpPtr = tmpPtr.prev

    def __setitem__(self, key, val):
        assert isinstance(key, int)
        self.insert(key, val)

    def __delitem__(self, key):
        assert isinstance(key, int)
        self.remove(key)

    def __getitem__(self, key):
        assert isinstance(key, int)
        assert key >= 0 and key < self.length

        tmpPtr = self.head.next
        while key > 0:
            tmpPtr = tmpPtr.next
            key -= 1

        return tmpPtr.data


def print_iter(l): # l 必须是可迭代的,
    # 怎么看迭代:要看__ iter__魔法方法
    # 关键是 迭代器和这个是怎么关联的.这下面这个是没有用到 iter 这个,只是用到
    # range 里面的 len()
    for x in l: #这个才用到 iter 系统会解释器会找到相应的迭代方法
        print(l[x-1])
        # l.__getitem__(1) # 结果为空啊 !!!
    # for l in range(0, len(x)):
    #     print(x[l])


if __name__ == "__main__":
    l = List()
    l.append(1)
    l.append(2)
    l.append(3)
    l.append(4)

    print_iter(l)


